<?php
namespace App\ModelStatistic;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Input;

// 临时使用账号系统计算留存
class RetainAccountTemp extends  Model{
    
    const RETAIN_STEP = 86400;

	public function paginate()
    {
        

    	$perPage = Request::get('per_page', 100);

        $page = Request::get('page', 1);
        $valid = Input::get('valid', 1);
        
        $start = ($page-1)*$perPage;

        $qdCond = StatisticCommon::remainChartDate(Request::get('retain_time'));
       
        $list = $this->generate($qdCond['start'], $qdCond['end'], $valid);
        $list_un = $this->generate($qdCond['start'], $qdCond['end'], $valid ? 0:1);

        // 总计
        $total_item = [];
        $total_item_un = [];
        foreach ($list as $k => $item_list) {
            foreach ($item_list as $attr => $item_val) {
                if ($attr == 'retain_time') {
                    $total_item['retain_time'] = 'total';
                } else {
                    $total_item[$attr] += $item_val;
                }
            }

        }
        foreach($list_un as $kk => $ot) {
            foreach ($ot as $attr => $item_val) {
                if ($attr == 'retain_time') {
                    $total_item_un['retain_time'] = 'total';
                } else {
                    $total_item_un[$attr] += $item_val;
                }
            } 
        }

        foreach($list as $k => $item_list) {
            $denominator = $item_list['retain_num'];
            $molecule = $list_un[$k]['retain_num'];
            if ($valid) 
            {
                $molecule = $item_list['retain_num'];
                $denominator = $list_un[$k]['retain_num'];
            }
            $list[$k]['retain_fuck'] = $molecule . '/' . $denominator .'<br>'. (round($molecule/$denominator, 2)*100) . "%";
        }

        if (!empty($total_item)) {
            $denominator = $total_item['retain_num'];
            $molecule = $total_item_un['retain_num'];
            if ($valid) {
                $molecule = $total_item['retain_num'];
                $denominator = $total_item_un['retain_num'];
            }
            $total_item['retain_fuck'] = $molecule . '/' . $denominator .'<br>'. (round($molecule/$denominator, 2)*100) . "%";
            $list[] = $total_item;
        }
        
        
        \App\ModelStatistic\StatisticCommon::arrayFieldSort($list, 'retain_time');
        
        $total = count($list);
        $list = static::hydrate($list);
        $paginator = new LengthAwarePaginator($list, $total, $perPage);

        $paginator->setPath(url()->current());

        return $paginator;
    }

    // 查询数据库
    public function generate($start, $end, $valid = 1)
    {
        if (!$end || $end > time()){
            $end = time();
        }
        if (intval($start) !== $start) {
            $start = strtotime($start);
        }
        if (intval($end) !== $end) {
            $end = strtotime($end);
        }
        // 开始时间 和 区服未选择的话，直接只做查询不做统计
        if (!$start || $start > $end){
            \Log::debug(__METHOD__, ["mabay empty start:" . $start, "mabay start > end:{$end}", "so cant generate statistic data"]);
            return;
        }
        
        
        $list = [];
        

        $start = strtotime(date("Y-m-d", $start));
        $end = strtotime(date("Y-m-d", $end));
        $end_count = ($end - $start)/self::RETAIN_STEP;
        // 最多做100条统计
        ($end_count > 100) && $end_count = 100;
        $cur_int = strtotime(date("Y-m-d"));
        \Log::Debug('[RETAIN_ACCOUNT][BY_ACCOUNT_INFO][generate]', [date('Y-m-d', $start), date('Y-m-d', $end)]);

        $all_data = $total_data = [];
        for ($step = 0; $step <= $end_count; $step++) {
            // 查询一个月的数据做计算 留存
            $start_time = $start + $step * self::RETAIN_STEP;
            $query_end_time = $start_time + 30 * self::RETAIN_STEP;

            $account_ids = $this->getAccountIds($start_time, $start_time+ self::RETAIN_STEP, $valid);
            // 组织留存数据
            $data_tmp = [];
            $data_tmp['retain_time'] = $start_time;
            

            $data_tmp['retain_num'] = count($account_ids);

            if (!$data_tmp['retain_num']) {
                continue;
            }

            $data_retain = $this->getRetain($account_ids, $start_time+ self::RETAIN_STEP , $query_end_time);

            foreach ($data_retain as $k => $v) {
                $data_tmp['day'.$k]  = $v;
            }
            if (empty ( $data_tmp)) {
                continue;
            }
            $all_data[$start_time] = $data_tmp;
        }

        return $all_data;
    }

    // 统计的账号ids
    public function getAccountIds($start, $end, $valid = null) {
        $rw = \DB::connection('mysql_bgac')->table('account_info')->select('account')->where('createTime','>=', date('Y-m-d', $start))->where('createTime', '<=', date('Y-m-d', $end));
        if ($valid) {
            $rw->where('lastPlayerId', '>', 0);
        }
        self::filterIosWhere($rw);
        $list = $rw->get()->toArray();

        $account_ids = [];
        foreach ($list as $obj) {
            $account_ids[] = $obj->account;
        }
        return $account_ids;
    }

    //
    public function getRetain($account_ids, $start , $end) {
        $rw = \DB::connection('mysql_bgac')->table('account_info')->select(\DB::raw('count(account) as total '), \DB::raw('LEFT(lastLoginTime,10) as login_format'))
        ->whereIn('account', $account_ids)->where('lastLoginTime','>=', date('Y-m-d', $start));//->where('lastLoginTime', '<=', date('Y-m-d', $end + 2 * 86400))
        self::filterIosWhere($rw);

        $list = $rw->groupBy(\DB::raw('LEFT(lastLoginTime,10) ') )
        ->orderBy('login_format', 'ASC')
        ->get()->toArray();

        $data = $test_valid = [];
        
        foreach ($list as $obj) {
            $tmp_time = strtotime($obj->login_format);
            $tmp_int = ($tmp_time - $start) / self::RETAIN_STEP + 1;
            
            for ($i =1; $i <= $tmp_int; $i++ ) {
                $data[$i] += $obj->total;
            }
            $test_valid[] = [$obj->total , $obj->login_format];
            $data[$tmp_int] = $obj->total;
        }
        \Log::debug('[RETAIN_ACCOUNT][BY_ACCOUNT_INFO][getRetain]', ['start'=> date('Y-m-d', $start), 'end'=>date('Y-m-d', $end)]);
        \Log::debug('[RETAIN_ACCOUNT][BY_ACCOUNT_INFO_SELECT]', ['data'=> $data, 'test' => $test_valid]);
        return $data;
    }

    public static function filterIosWhere($rw) {
        $model = Request::get('mmodel', "");
        if (empty($model)) {
            return;
        }

        if (mb_strtolower($model) == "ios") {
            $rw->where(function($query) {
                $query->orWhere("udid", "like", "ios%")->orWhere("udid", 'like', "iphone");
            });
        } else {
            $rw->where(function($query) {
                $query->where("udid", "not like", "ios%")->where("udid", 'not like', "iphone");
            });
        }
    }
}